﻿using CommunityToolkit.Mvvm.ComponentModel;
using Koala.Pro.Common;
using Koala.Pro.Common.Extension;
using Koala.Pro.Core.Dto;
using Koala.Pro.Core.Models;
using Koala.Pro.Helpers;
using Koala.Pro.Models;
using Koala.Pro.Services;
using Koala.Pro.Services.Role;

namespace Koala.Pro.ViewModels
{
    public partial class RoleEditViewModel : BaseEditViewModel<RoleInfo, int, RolePagedDto>
    {
        [ObservableProperty]
        private List<CListItem> userInfos = new List<CListItem>();

        [ObservableProperty]
        private List<CListItem> ouInfos = new List<CListItem>();

        [ObservableProperty]
        private TreeViewModel<CustomTreeNode> functionTreeModel = new TreeViewModel<CustomTreeNode>();

        [ObservableProperty]
        private TreeViewModel<CustomTreeNode> dataTreeModel = new TreeViewModel<CustomTreeNode>();

        [ObservableProperty]
        private TreeViewModel<CustomTreeNode> menuTreeModel = new TreeViewModel<CustomTreeNode>();

        public RoleEditViewModel(IRoleService service)
            : base(service)
        {
            base.Title = "角色信息";
        }

        protected override async Task<bool> InsertOrUpdate()
        {
            bool success = await base.InsertOrUpdate();
            if (success && base.IsEdit)
            {
                int roleId = base.Item.Id;
                string typeId = App.ViewModel.SystemType;
                List<string> functions = (from s in FunctionTreeModel?.TreeItems?.FindCustomNodes((CustomTreeNode s) => s.IsChecked == true && !s.Id.IsNullOrWhiteSpace())
                                          select s.Id).ToList();
                List<string> menus = (from s in MenuTreeModel?.TreeItems?.FindCustomNodes((CustomTreeNode s) => s.IsChecked == true && !s.Id.IsNullOrWhiteSpace())
                                      select s.Id).ToList();
                List<string> values = (from s in DataTreeModel?.TreeItems?.FindCustomNodes((CustomTreeNode s) => s.IsChecked == true && s.Note == "company" && !s.Id.IsNullOrWhiteSpace())
                                       select s.Id).ToList();
                List<string> values2 = (from s in DataTreeModel?.TreeItems?.FindCustomNodes((CustomTreeNode s) => s.IsChecked == true && s.Note == "dept" && !s.Id.IsNullOrWhiteSpace())
                                        select s.Id).ToList();
                string companyString = string.Join(",", values);
                string deptDataString = string.Join(",", values2);
                await BLLFactory<IRoleService>.Instance.UpdateRoleFunctions(new UpdateRoleFunctionsDto
                {
                    RoleId = roleId,
                    SystemType = typeId,
                    Functions = functions
                });
                await BLLFactory<IRoleService>.Instance.UpdateRoleMenus(new UpdateRoleMenusDto
                {
                    RoleId = roleId,
                    SystemType = typeId,
                    Menus = menus
                });
                await BLLFactory<IRoleDataService>.Instance.UpdateRoleData(roleId, companyString, deptDataString);
            }
            return success;
        }

        public async Task InitData(int id)
        {
            List<UserInfo> source = await BLLFactory<IUserService>.Instance.GetUsersByRole(id);
            UserInfos.Clear();
            List<CListItem> collection = source.Select((UserInfo s) => new CListItem(s.FullName + "（" + s.Name + "）", s.Id)).ToList();
            UserInfos.AddRange(collection);
            NotifyChanged("UserInfos");
           
            List<OuInfo> source2 = await BLLFactory<IOuService>.Instance.GetOUsByRole(id);
            OuInfos.Clear();
            OuInfos.AddRange(source2.Select((OuInfo s) => new CListItem(s.Name + "（" + s.CompanyName + "）", s.Id)));
            NotifyChanged("OuInfos");
          
            await InitFunction(id);
            await InitDataScope(id);
            await InitMenu(id);
        }

        private async Task InitFunction(int roleId)
        {
            string typeId = App.ViewModel.SystemType;
            SystemTypeInfo systemTypeInfo = await BLLFactory<ISystemTypeService>.Instance.GetAsync(typeId);
            if (systemTypeInfo == null)
            {
                return;
            }
            CustomTreeNode topNode = new CustomTreeNode
            {
                Name = systemTypeInfo.Name,
                IsChecked = true
            };
            new List<FunctionInfo>();
            List<FunctionInfo> allNode = ((!App.ViewModel.IsSuperAdmin) ? (await BLLFactory<IFunctionService>.Instance.GetFunctionNodesByUser(App.ViewModel.UserInfo.Id, typeId)) : (await BLLFactory<IFunctionService>.Instance.GetTree(systemTypeInfo.Id)));
            Dictionary<string, string> dictContain = new Dictionary<string, string>();
            foreach (FunctionInfo item in await BLLFactory<IFunctionService>.Instance.GetFunctionsByRole(roleId, typeId))
            {
                if (!dictContain.ContainsKey(item.Id))
                {
                    dictContain.Add(item.Id, item.Id);
                }
            }
            List<CustomTreeNode> list = AddFunctionRecursive(dictContain, allNode, topNode);
            FunctionTreeModel.TreeItems = list;
            FunctionTreeModel.FilteredTreeItems = new List<CustomTreeNode>(list);
            NotifyChanged("FunctionTreeModel");
        }

        private async Task InitDataScope(int roleId)
        {
            Dictionary<int, int> dictContain = await BLLFactory<IRoleDataService>.Instance.GetRoleDataDict(roleId);
            List<CustomTreeNode> allNode = new List<CustomTreeNode>();
            int key = -1;
            int key2 = -11;
            CustomTreeNode customTreeNode = new CustomTreeNode
            {
                Name = "所在公司",
                Id = key.ToString(),
                Note = "company",
                IsChecked = dictContain.ContainsKey(key)
            };
            customTreeNode.Children.Add(new CustomTreeNode
            {
                Name = "所在部门",
                Note = "dept",
                Id = key2.ToString(),
                IsChecked = dictContain.ContainsKey(key2)
            });
            allNode.Add(customTreeNode);
            foreach (OuInfo item in await SecurityHelper.GetMyTopGroup(App.ViewModel.UserInfo))
            {
                if (item != null)
                {
                    List<CustomTreeNode> collection = AddDataRecursive(parentNode: new CustomTreeNode
                    {
                        Name = item.Name,
                        Id = item.Id.ToString(),
                        IsChecked = dictContain.ContainsKey(item.Id),
                        Note = (item.Company_ID.IsNullOrEmpty() ? "company" : "dept")
                    }, dictContaint: dictContain, children: await BLLFactory<IOuService>.Instance.GetTreeByID(item.Id));
                    allNode.AddRange(collection);
                }
            }
            DataTreeModel.TreeItems = allNode;
            DataTreeModel.FilteredTreeItems = new List<CustomTreeNode>(allNode);
            NotifyChanged("DataTreeModel");
        }

        private async Task InitMenu(int roleId)
        {
            string typeId = App.ViewModel.SystemType;
            SystemTypeInfo systemTypeInfo = await BLLFactory<ISystemTypeService>.Instance.GetAsync(typeId);
            if (systemTypeInfo != null)
            {
                CustomTreeNode topNode = new CustomTreeNode
                {
                    Name = systemTypeInfo.Name,
                    IsChecked = true,
                    Icon = "Home24"
                };
                new List<MenuInfo>();
                List<MenuInfo> allNode = ((!App.ViewModel.IsSuperAdmin) ? (await BLLFactory<IMenuService>.Instance.GetMenuNodesByUser(App.ViewModel.UserInfo.Id, systemTypeInfo.Id)) : (await BLLFactory<IMenuService>.Instance.GetTree(systemTypeInfo.Id)));
                Dictionary<string, string> dictContain = new Dictionary<string, string>();
                foreach (MenuInfo item in await BLLFactory<IMenuService>.Instance.GetMenusByRole(roleId, typeId))
                {
                    if (!dictContain.ContainsKey(item.Id))
                    {
                        dictContain.Add(item.Id, item.Id);
                    }
                }
                List<CustomTreeNode> list = AddMenuRecursive(dictContain, allNode, topNode);
                MenuTreeModel.TreeItems = list;
                MenuTreeModel.FilteredTreeItems = new List<CustomTreeNode>(list);
            }
            NotifyChanged("MenuTreeModel");
        }

        private List<CustomTreeNode> AddFunctionRecursive(Dictionary<string, string> dictContaint, List<FunctionInfo> children, CustomTreeNode parentNode = null)
        {
            List<CustomTreeNode> list = new List<CustomTreeNode>();
            foreach (FunctionInfo child in children)
            {
                CustomTreeNode parentNode2 = new CustomTreeNode
                {
                    Name = child.Name,
                    Id = child.Id,
                    IsChecked = dictContaint.ContainsKey(child.Id)
                };
                AddFunctionRecursive(dictContaint, child.Children, parentNode2);
                list.Add(parentNode2);
            }
            if (parentNode != null)
            {
                parentNode.Children = list;
                return new List<CustomTreeNode> { parentNode };
            }
            return list;
        }

        private List<CustomTreeNode> AddMenuRecursive(Dictionary<string, string> dictContaint, List<MenuInfo> children, CustomTreeNode parentNode = null)
        {
            List<CustomTreeNode> list = new List<CustomTreeNode>();
            foreach (MenuInfo child in children)
            {
                CustomTreeNode parentNode2 = new CustomTreeNode
                {
                    Name = child.Name,
                    Id = child.Id,
                    IsChecked = dictContaint.ContainsKey(child.Id),
                    Icon = child.Icon
                };
                AddMenuRecursive(dictContaint, child.Children, parentNode2);
                list.Add(parentNode2);
            }
            if (parentNode != null)
            {
                parentNode.Children = list;
                return new List<CustomTreeNode> { parentNode };
            }
            return list;
        }

        private List<CustomTreeNode> AddDataRecursive(Dictionary<int, int> dictContaint, List<OuInfo> children, CustomTreeNode parentNode = null)
        {
            List<CustomTreeNode> list = new List<CustomTreeNode>();
            foreach (OuInfo child in children)
            {
                CustomTreeNode parentNode2 = new CustomTreeNode
                {
                    Name = child.Name,
                    Id = child.Id.ToString(),
                    IsChecked = dictContaint.ContainsKey(child.Id),
                    Note = (child.Company_ID.IsNullOrEmpty() ? "company" : "dept")
                };
                AddDataRecursive(dictContaint, child.Children, parentNode2);
                list.Add(parentNode2);
            }
            if (parentNode != null)
            {
                parentNode.Children = list;
                return new List<CustomTreeNode> { parentNode };
            }
            return list;
        }
    }
}
